package com.jingdianjichi.subject.domain.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.*;

/**
 * 这里管理我们项目中我们所有线程池的分配
 *  /自定义是方便灵活的亲,我们黑马使用的就是 newFixedThreadPool
 *      我们做队列的时候我们还可以指定队列的,不会产生队列的溢出的
 */
@Configuration
public class ThreadPoolConfig {

    //返回线程池
    @Bean(name = "labelThreadPool")        //用bean来区分不同的线程池
    public ThreadPoolExecutor getLabelThreadPool(){
        return new ThreadPoolExecutor(20,100,5, TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(40),
                //, Executors.defaultThreadFactory()
                new CustomNameThreadFactory("label")        //用我们自定义的,这样打印日志的时候都是我们自己的名字亲
                ,new ThreadPoolExecutor.CallerRunsPolicy());
        /*
            corePoolSize (20):
                这是线程池的基本大小，当线程池创建时，会初始化为这个数量的线程。即使这些线程处于空闲状态，它们仍然会保持在线，不会被回收，直到调用 allowCoreThreadTimeOut(true) 方法。

            maximumPoolSize (100):
                这是线程池可以容纳的最大线程数。当活跃的线程数超过 corePoolSize 且队列已经满时，线程池会增加线程数量，直到达到这个最大值。

            keepAliveTime (5):
                这是非核心线程的最大空闲时间。当线程池中的线程数超过 corePoolSize 时，那些空闲的非核心线程在保持空闲状态超过这个时间后，会被终止（回收）。

            timeUnit (TimeUnit.SECONDS):
                这个参数指定了 keepAliveTime 参数的时间单位，使用 SECONDS 表示时间单位为秒。

            workQueue (new LinkedBlockingDeque<>(40)):
                这是一个阻塞队列，用于存储等待执行的任务。本例中使用的是 LinkedBlockingDeque，它可以存储最多 40 个任务。如果线程池的活跃线程数达到 corePoolSize 且队列已满，
                    /会创建新的线程来处理任务，直到达到最大线程数量。

            threadFactory (Executors.defaultThreadFactory()):
                这是一个用于创建新线程的工厂，提供了创建线程的默认实施方式。可以定制线程的创建方式，比如设置线程的名字、优先级等。
                /我们后面做自定义的亲


            new ThreadPoolExecutor.CallerRunsPolicy()
                /是任务的拒绝策略,就是100个用完了,队列也满了怎么办
                1. AbortPolicy
                    这是默认的饱和策略。当线程池和队列都满时，这个策略会直接抛出一个 RejectedExecutionException，表示任务无法被接收。
                        /不行你抛异常,会导致可用性降低的亲


                2. CallerRunsPolicy
                    如之前所述，当任务被拒绝时，当前提交任务的线程会直接执行这个任务。这有助于平均减轻系统负载，但可能会影响调用线程的响应性。


                3. DiscardPolicy
                    这个策略会 silently 不处理被拒绝的任务，也就是说被拒绝的任务将不做任何动作（没有异常抛出，也没有任务执行）。该策略用于允许线程池的工作继续，而放弃那些不重要的任务。


                4. DiscardOldestPolicy
                    当拒绝一个新任务时，这个策略会丢弃队列中最旧的任务，然后尝试再次提交当前任务。这样可以确保在负载过高时，最新的任务能够优先得到处理。
         */
    }
}
